/*****************************************************
 * Risk 3d
 * 
 * Autheur : Youenn Bodiger & Benjamin LE FLOCH
 * Création: 01/10/2007
 *  
 /*****************************************************/

#include <iostream>
#include <vector>
#include <GL/glut.h>
#include <SDL/SDL_thread.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>

#include "Joueur.h"
#include "Combat.h"
#include "Territoire.h"
#include "Frontiere.h"
#include "Boulier.h"
#include "Loadppm.h"
#include "Continent.h"
#include "Monde.h"
#include "RiskFactory.h"
#include "Jeu.h"
#include "Audio.h"

#define BUFSIZE 512

float longueur = 800.0; // longueur de la fenetre
float hauteur = 600.0; // largeur de la fenetre
static GLuint texName[1]; // tableau de textures

PPMImage* data; // 

int width, height;
int winIdMain;
int winIdSub;

float eX = 0; // position de l'oeil en X
float eY = 0; // position de l'oeil en Y
float eZ = 500; // position de l'oeil en Z
float pasCamera = 5;

GLdouble posX, posY, posZ;

bool allumer = false; // dessiner le feu 	

// Pour l'affichage des menus
bool menuScore = true;
bool menuResultat = false;
bool menuAide = false;

bool loadIdentity = false;

// Affiche en (2d/3d)
bool vue3d = false;
bool vue2d = false;

// Pour le boulier
bool lancerAction = false;
bool initBoulier = false;

int menuContextTerritoire;

/*****************************************************
 * Chargement des fichiers sonores
 * - race des orcs
 * - race des humains
 * - jeu
 * - boulier
 ******************************************************/

// Race des orcs
char* OrcWhat1 = "./sons/OrcWhat1.wav";
char* OrcWhat2 = "./sons/OrcWhat2.wav";
char* OrcWhat3 = "./sons/OrcWhat3.wav";
char* OrcAttack1 = "./sons/OrcAttack1.wav";
char* OrcAttack2 = "./sons/OrcAttack2.wav";
char* OrcAttack3 = "./sons/OrcAttack3.wav";
char* OrcJobDone = "./sons/OrcJobDone.wav";

// Race des humains
char* HumainWhat1 = "./sons/HumainWhat1.wav";
char* HumainWhat2 = "./sons/HumainWhat2.wav";
char* HumainWhat3 = "./sons/HumainWhat3.wav";
char* HumainAttack1 = "./sons/HumainAttack1.wav";
char* HumainAttack2 = "./sons/HumainAttack2.wav";
char* HumainAttack3 = "./sons/HumainAttack3.wav";
char* HumainJobDone = "./sons/HumainJobDone.wav";

// Jeu 	
char* AddArmee = "./sons/AddArmee.wav";
char* DelArmee = "./sons/DelArmee.wav";
char* error = "./sons/error.wav";
char* ambiance1 = "./sons/ambiance1.wav";
char* ambiance2 = "./sons/ambiance2.wav";
char* feuBrule = "./sons/feu.wav";
char* depart = "./sons/depart.wav";
char* finPath = "./sons/fin.wav";

const int NUM_AMBIANCE_1 = 1;
const int NUM_AMBIANCE_2 = 2;
int numAmbianceCourante = NUM_AMBIANCE_1;

// Boulier
char* grincement = "./sons/grincement.wav";
char* rebond = "./sons/rebond.wav";
char* foudre = "./sons/foudre.wav";
char* tempete = "./sons/tempete.wav";
char* cri = "./sons/cri.wav";
char* ghost = "./sons/ghost.wav";
char* explosion = "./sons/explosion.wav";
char* AfficheAide = "./sons/AfficheAide.wav";

// Creation des du lecteur et des sources audios 
Lecteur lecteur;
float pasVolume = 0.1;

// Orc
Source sOrcWhat1(&lecteur, OrcWhat1);
Source sOrcWhat2(&lecteur, OrcWhat2);
Source sOrcWhat3(&lecteur, OrcWhat3);
Source sOrcAttack1(&lecteur, OrcAttack1);
Source sOrcAttack2(&lecteur, OrcAttack2);
Source sOrcAttack3(&lecteur, OrcAttack3);
Source sOrcJobDone(&lecteur, OrcJobDone);

// Humain
Source sHumainWhat1(&lecteur, HumainWhat1);
Source sHumainWhat2(&lecteur, HumainWhat2);
Source sHumainWhat3(&lecteur, HumainWhat3);
Source sHumainAttack1(&lecteur, HumainAttack1);
Source sHumainAttack2(&lecteur, HumainAttack2);
Source sHumainAttack3(&lecteur, HumainAttack3);
Source sHumainJobDone(&lecteur, HumainJobDone);

// Jeu
Source sError(&lecteur, error);
Source sAddArmee(&lecteur, AddArmee);
Source sDelArmee(&lecteur, DelArmee);
Source sAmbiance1(&lecteur, ambiance1);
Source sAmbiance2(&lecteur, ambiance2);
Source sDepart(&lecteur, depart);
Source sFin(&lecteur, finPath);
Source sExplosion(&lecteur, explosion);
Source sAfficheAide(&lecteur, AfficheAide);

// Boulier
Source sGrincement(&lecteur, grincement);
Source sRebond(&lecteur, rebond);
Source sFoudre(&lecteur, foudre);
Source sTempete(&lecteur, tempete);
Source sCri(&lecteur, cri);
Source sGhost(&lecteur, ghost);

// Musique de fond
LectureRVVB * lAmbianceCourante;

LectureRVVB * lAmbiance1 = LectureRVVB::creer_persistante(&sAmbiance1, 0.8, 1,
		1, Lecture::Stop, true);
LectureRVVB * lAmbiance2 = LectureRVVB::creer_persistante(&sAmbiance2, 1, 1, 1,
		Lecture::Stop, true);

// Musique du boulier
LectureRVVB * lGrincement = LectureRVVB::creer_persistante(&sGrincement, 1, 1,
		0.5, Lecture::Stop, true);
LectureRVVB * lCri = LectureRVVB::creer_persistante(&sCri, 0.1, 1, 0.5,
		Lecture::Stop, true);
LectureRVVB * lFoudre = LectureRVVB::creer_persistante(&sFoudre, 0.5, 1, 0.5,
		Lecture::Stop, true);
LectureRVVB * lGhost = LectureRVVB::creer_persistante(&sGhost, 0.7, 0.7, 0.5,
		Lecture::Stop, true);
LectureRVVB * lTempete = LectureRVVB::creer_persistante(&sTempete, 0.4, 1, 0.5,
		Lecture::Stop, true);

/***************************************************************/

// Variable qui determine l'action courrante 
int action;
const int ATTAQUER = 1;
const int PLACER = 2;

// Tableau de joueur et de territoires
vector<Joueur *> lesJoueurs;
vector<Territoire*> lesTerritoires;

// Determine le territoire en cours et le joueur en cours
Territoire* territoireEnCours;
Joueur* joueurEnCours;

Boulier* boulier;
Combat* combat;
Combat* combatAffichage;
Jeu* risk;
Monde* leMonde;
RiskFactory* riskFactory;

/****************************************************
 * Gestion des erreurs
 ****************************************************/
static const int NO_MESSAGE = 0;
static const int COMBAT_NO_FRONTIERE = 1;
static const int COMBAT_OWN_CIBLE = 2;
static const int SELECTION_AUTRE_USER = 3;
static const int NO_ARMEE_REST = 4;
static const int UNE_ARMEE_MIN = 5;
static const int MUSIQUE_CGH = 6;

int messageErreur = NO_MESSAGE;

const char* MESS_COMBAT_NO_FRONTIERE =
		"Il n'existe pas de frontiere entre les deux territoires";
const char* MESS_COMBAT_OWN_CIBLE =
		"Vous ne pouvez pas attaquer un de vos territoires";
const char* MESS_SELECTION_AUTRE_USER =
		"Veuillez choisir un de vos territoires";
const char* MESS_NO_ARMEE_REST = "Vous n'avez pas d'armee disponible";
const char* MESS_UNE_ARMEE_MIN =
		"Vous devez laisser au moins une armee sur le territoire";
const char* MESS_MUSIQUE_CGH = "Changement de la musique d'ambiance";
/****************************************************************************************/

// Definition des fonction qui seront lancees par les threads SDL
int what(void * param);
int attack(void * param);
int jobDone(void * param);
int explose(void * param);
int demarre(void * param);
int erreur(void * param);
int addArmee(void * param);
int delArmee(void * param);
int aide(void * param);
int fin(void * param);
void changeMusiqueAmbiance(int numAmbiance);

void timerVue3d(int id);
void timerVue2d(int id);

/**********************************************************
 * Affiche une chaine de caratere avec la font voulue
 **********************************************************/
static void printstring(void *font, const char *string) {

	int len, i;

	len = (int) strlen(string);
	for (i = 0; i < len; i++)
		glutBitmapCharacter(font, string[i]);
}

/**********************************************************
 * Menu des scores et messages d'erreurs/notifications
 **********************************************************/
static void afficheMenuScores(void) {

	Joueur* joueur1 = lesJoueurs[0];
	Joueur* joueur2 = lesJoueurs[1];

	char * armeeTotal="Nombre d'armees total";
	char * armeePlace="Nombre d'armees sur territoire";
	char * armeeDsiponible="Nombre d'armees disponibles";
	char * territoireJoueur="Nombre de territoires";

	const char* nomJoueur1 = joueur1->getNom().c_str();
	const char* nomJoueur2 = joueur2->getNom().c_str();
	const char* nomJoueurEnCours = joueurEnCours->getNom().c_str();

	char * tmp=(char*)malloc(sizeof(char)*100);

	glDisable(GL_DEPTH_TEST);
	glDisable(GL_FOG);
	glShadeModel(GL_FLAT);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glOrtho(-0.5, 639.5, -0.5, 479.5, -1.0, 1.0);

	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	glColor4f(0.0, 0.0, 0.0, 0.5);
	glRecti(10, 10, 630, 100);

	if (action == ATTAQUER && combat == NULL) {

		glColor4f(0.0, 0.0, 0.0, 0.5);
		glRecti(180, 270, 450, 300);

		glColor3f(1.0, 1.0, 1.0);
		glRasterPos2i(200, 280);
		printstring(GLUT_BITMAP_TIMES_ROMAN_24, "     Choisissez le pays cible");
	}

	glDisable(GL_BLEND);

	glColor3f(1.0, 1.0, 1.0);
	glRasterPos2i(300, 80);

	printstring(GLUT_BITMAP_HELVETICA_18, "Scores");

	glColor3fv(joueur1->couleur);

	glRasterPos2i(50, 90);
	printstring(GLUT_BITMAP_HELVETICA_12, nomJoueur1);

	glRasterPos2i(50, 70);
	sprintf(tmp, "%s : %d", armeeTotal, joueur1->getNbArmeeTotal());
	printstring(GLUT_BITMAP_HELVETICA_10, tmp);

	/*
	 glRasterPos2i(50, 60);
	 sprintf(tmp, "%s : %d", armeePlace, joueur1->getNbArmeePlace());
	 printstring(GLUT_BITMAP_HELVETICA_10, tmp);
	 */
	glRasterPos2i(50, 55);
	sprintf(tmp, "%s : %d", armeeDsiponible, joueur1->getNbArmeeDisponible());
	printstring(GLUT_BITMAP_HELVETICA_10, tmp);

	glRasterPos2i(50, 40);
	sprintf(tmp, "%s : %d", territoireJoueur, joueur1->getTerritoires().size());
	printstring(GLUT_BITMAP_HELVETICA_10, tmp);

	glColor3fv(joueur2->couleur);

	glRasterPos2i(450, 90);
	printstring(GLUT_BITMAP_HELVETICA_12, nomJoueur2);

	glRasterPos2i(450, 70);
	sprintf(tmp, "%s : %d", armeeTotal, joueur2->getNbArmeeTotal());
	printstring(GLUT_BITMAP_HELVETICA_10, tmp);

	glRasterPos2i(450, 55);
	sprintf(tmp, "%s : %d", armeeDsiponible, joueur2->getNbArmeeDisponible());
	printstring(GLUT_BITMAP_HELVETICA_10, tmp);

	glRasterPos2i(450, 40);
	sprintf(tmp, "%s : %d", territoireJoueur, joueur2->getTerritoires().size());
	printstring(GLUT_BITMAP_HELVETICA_10, tmp);

	glColor3f(1.0, 1.0, 1.0);
	glRasterPos2i(250, 20);

	// Gestion des messages d'erreurs et Information

	switch (messageErreur) {

	case COMBAT_NO_FRONTIERE:
		printstring(GLUT_BITMAP_HELVETICA_12, MESS_COMBAT_NO_FRONTIERE);
		messageErreur = NO_MESSAGE;
		break;

	case COMBAT_OWN_CIBLE:
		printstring(GLUT_BITMAP_HELVETICA_12, MESS_COMBAT_OWN_CIBLE);
		messageErreur = NO_MESSAGE;
		break;

	case SELECTION_AUTRE_USER:
		printstring(GLUT_BITMAP_HELVETICA_12, MESS_SELECTION_AUTRE_USER);
		messageErreur = NO_MESSAGE;
		break;

	case NO_ARMEE_REST:
		printstring(GLUT_BITMAP_HELVETICA_12, MESS_NO_ARMEE_REST);
		messageErreur = NO_MESSAGE;
		break;

	case UNE_ARMEE_MIN:
		printstring(GLUT_BITMAP_HELVETICA_12, MESS_UNE_ARMEE_MIN);
		messageErreur = NO_MESSAGE;
		break;

	case MUSIQUE_CGH:
		printstring(GLUT_BITMAP_HELVETICA_12, MESS_MUSIQUE_CGH);
		messageErreur = NO_MESSAGE;
		break;
	default:
		printstring(GLUT_BITMAP_HELVETICA_12, nomJoueurEnCours);
		printstring(GLUT_BITMAP_HELVETICA_12, " a vous de jouer");

		break;
	}

}

/**********************************************************
 * menu d'aide
 **********************************************************/
static void afficheMenuAide(void) {

	char * aideTitre = "Liste des raccourcis clavier";

	//char * xMess = "x :  avancer la camera sur l'axe des x";
	//char * XMess = "X :  reculer la camera sur l'axe des x";
	//char * yMess = "y :  avancer la camera sur l'axe des y";
	//char * YMess = "Y :  reculer la camera sur l'axe des y";
	//char * zMess = "y :  avancer la camera sur l'axe des z";
	//char * ZMess = "Y :  reculer la camera sur l'axe des z";
	char * hMess = "h :  afficher/masquer le menu d'aide";
	char * sMess = "haut   :  augmenter le volume";
	char * SMess = "bas    :  diminuer le volume";
	char * fMess = "droite :  changer la musique de fond";
	char * oMess = "o :  remettre les coordonnees d'origines";
	char * Mess0 = "0 :  reset du terriotire en cours";
	char * Mess2 = "2 :  vue 2 dimensions";
	char * Mess3 = "3 :  vue 3 dimensions";
	char * pMess = "+ :  ajouter une armee sur le territoire";
	char * mMess = "- :  enlever une armee sur le territoire";
	char * aMess = "a :  attaquer un territoire";
	char * rMess = "r :  masquer le menu de resultat";
	char * qMess = "entrer :  quitter le boulier";

	glDisable(GL_DEPTH_TEST);
	glDisable(GL_FOG);
	glShadeModel(GL_FLAT);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glOrtho(-0.5, 639.5, -0.5, 479.5, -1.0, 1.0);

	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	glColor4f(0.0, 0.0, 0.0, 0.5);

	glRecti(180, 180, 400, 420);
	glDisable(GL_BLEND);

	glColor3f(1.0, 1.0, 1.0);

	glRasterPos2i(200, 400);
	printstring(GLUT_BITMAP_HELVETICA_18, aideTitre);
	glRasterPos2i(200, 380);
	printstring(GLUT_BITMAP_HELVETICA_12, hMess);
	glRasterPos2i(200, 365);
	printstring(GLUT_BITMAP_HELVETICA_12, sMess);
	glRasterPos2i(200, 350);
	printstring(GLUT_BITMAP_HELVETICA_12, SMess);
	glRasterPos2i(200, 335);
	printstring(GLUT_BITMAP_HELVETICA_12, fMess);
	glRasterPos2i(200, 320);
	printstring(GLUT_BITMAP_HELVETICA_12, oMess);
	glRasterPos2i(200, 305);
	printstring(GLUT_BITMAP_HELVETICA_12, Mess0);
	glRasterPos2i(200, 290);
	printstring(GLUT_BITMAP_HELVETICA_12, Mess2);
	glRasterPos2i(200, 275);
	printstring(GLUT_BITMAP_HELVETICA_12, Mess3);
	glRasterPos2i(200, 260);
	printstring(GLUT_BITMAP_HELVETICA_12, pMess);
	glRasterPos2i(200, 245);
	printstring(GLUT_BITMAP_HELVETICA_12, mMess);
	glRasterPos2i(200, 230);
	printstring(GLUT_BITMAP_HELVETICA_12, aMess);
	glRasterPos2i(200, 215);
	printstring(GLUT_BITMAP_HELVETICA_12, rMess);
	glRasterPos2i(200, 200);
	printstring(GLUT_BITMAP_HELVETICA_12, qMess);
}

/**********************************************************
 * menu des resultats
 **********************************************************/
static void afficheMenuResultat(void) {

	char * tmp=(char*)malloc(sizeof(char)*100);

	char* titreResultat = "Resultat du combat";
	char* nomAttaquant = "Attaquant : ";
	char* nomDefenseur = "Defenseur : ";
	char* nomTerritoire = "Territoire : ";
	char* nbArmeePerdue = "Nombre armee(s) perdue(s) = ";
	char* nbArmeeGagne = "Nombre armee(s) gagnee(s) = ";
	char* line = "----------------------------";
	char* quitter = "taper r pour masquer les resultats";

	glDisable(GL_DEPTH_TEST);
	glDisable(GL_FOG);
	glShadeModel(GL_FLAT);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glOrtho(-0.5, 639.5, -0.5, 479.5, -1.0, 1.0);

	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	glColor4f(0.0, 0.0, 0.0, 0.5);
	glRecti(180, 180, 400, 420);
	glDisable(GL_BLEND);

	glColor3f(1.0, 1.0, 1.0);

	glRasterPos2i(200, 400);	
	printstring(GLUT_BITMAP_HELVETICA_18, titreResultat);	
	
	glColor3fv(combatAffichage->getAttaquant()->couleur);
	glRasterPos2i(200, 370);
	printstring(GLUT_BITMAP_HELVETICA_10, nomAttaquant);	
	printstring(GLUT_BITMAP_HELVETICA_10, combatAffichage->getAttaquant()->getNom().c_str());
	glColor3f(1.0, 1.0, 1.0);
	
	glRasterPos2i(200, 355);
	printstring(GLUT_BITMAP_HELVETICA_10, nomTerritoire);
	printstring(GLUT_BITMAP_HELVETICA_10, combatAffichage->getPaysAttaque()->getNom().c_str());

	glRasterPos2i(200, 340);
	sprintf(tmp, "%s %d", nbArmeePerdue,
			combatAffichage->getNbArmeePerduAttaque());
	printstring(GLUT_BITMAP_HELVETICA_10, tmp);

	glRasterPos2i(200, 325);
	sprintf(tmp, "%s %d", nbArmeeGagne, combatAffichage->getScoreAttaque());
	printstring(GLUT_BITMAP_HELVETICA_10, tmp);

	glRasterPos2i(200, 310);
	printstring(GLUT_BITMAP_HELVETICA_10, line);

	glColor3fv(combatAffichage->getDefenseur()->couleur);
	glRasterPos2i(200, 290);		
	printstring(GLUT_BITMAP_HELVETICA_10, nomDefenseur);
	printstring(GLUT_BITMAP_HELVETICA_10, combatAffichage->getDefenseur()->getNom().c_str());
	glColor3f(1.0, 1.0, 1.0);

	glRasterPos2i(200, 275);
	printstring(GLUT_BITMAP_HELVETICA_10, nomTerritoire);
	printstring(GLUT_BITMAP_HELVETICA_10, combatAffichage->getPaysDefense()->getNom().c_str());

	glRasterPos2i(200, 260);
	sprintf(tmp, "%s %d", nbArmeePerdue,
			combatAffichage->getNbArmeePerduDefense());
	printstring(GLUT_BITMAP_HELVETICA_10, tmp);
	
	 glRasterPos2i(200, 245);
	 sprintf(tmp, "%s %d", nbArmeeGagne, combatAffichage->getScoreDefense());
	 printstring(GLUT_BITMAP_HELVETICA_10, tmp);

	glRasterPos2i(200, 215);
	printstring(GLUT_BITMAP_HELVETICA_12, quitter);
}

/**********************************************************
 * Initialisation de la texture de la carte
 **********************************************************/
void initTexCarte() {

	cout << "init texture carte... "<< endl;

	data = new PPMImage("./images/riskmap_gimp.ppm");

	glBindTexture(GL_TEXTURE_2D, texName[0]);
	glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

	gluBuild2DMipmaps(GL_TEXTURE_2D, 3, data->sizeX, data->sizeY,
	GL_RGB, GL_UNSIGNED_BYTE, data->data);
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
}

/**********************************************************
 * Dessine la carte
 **********************************************************/
void drawCarte(GLenum mode) {

	cout << "===> DRAW CARTE" << endl;

	int mi_long = (int)(longueur/2);
	int mi_haut = (int)(hauteur/2);

	if (mode == GL_SELECT) {
		cout<<"mode selection de la carte..."<<endl;
		glLoadName(1000);
	}

	glPushMatrix();
	glColor3f(1.0f, 1.0f, 1.0f);

	glEnable(GL_TEXTURE_2D);

	glBindTexture(GL_TEXTURE_2D, texName[0]);

	glTranslatef(-mi_long, -mi_haut, 0);

	glBegin(GL_POLYGON);
	glTexCoord2f(0.0, 0.0);
	glVertex3f(0.0, 0.0, 0.0);
	glTexCoord2f(0.0, 1.0);
	glVertex3f(0.0, hauteur, 0.0);
	glTexCoord2f(1.0, 1.0);
	glVertex3f(longueur, hauteur, 0.0);
	glTexCoord2f(1.0, 0.0);
	glVertex3f(longueur, 0.0, 0.0);
	glEnd();

	glDisable(GL_TEXTURE_2D);

	glPopMatrix();
}

/**********************************************************
 * Dessine les territoires avec gestion du picking
 **********************************************************/
void drawTerritoire(GLenum mode) {

	cout << "===> DRAW TERRITOIRE" << endl;

	for (int i=0; i < lesTerritoires.size(); i++) {

		Territoire* territoire = lesTerritoires[i];

		// Si on est en mode select
		if (mode == GL_SELECT) {

			// On donne un identifiant a l'objet que l'on dessine
			glLoadName(territoire->getId());
		}

		territoire->draw();
	}
}

/**********************************************************
 * Dessine la scene (placement camera, carte, territoire)
 **********************************************************/
void drawScene(GLenum mode) {
	cout << "===> DRAW SCENE" << endl;
	glPushMatrix();

	// Position de l'oeil
	gluLookAt(eX, eY, eZ, 0, 0, 0, 0.0, 1.0, 0.0);

	// dessine la carte	
	drawCarte(mode);

	// dessine les territoires
	drawTerritoire(mode);

	glFlush();
	glPopMatrix();
}

/**********************************************************
 * Reshape
 **********************************************************/
void reshape(int w, int h) {

	glViewport(0, 0, (GLsizei) w, (GLsizei) h);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(60, longueur/hauteur, 1, 2000);
	if (combat != NULL)
		boulier->reshape(w, h);
}

/**********************************************************
 * Display
 **********************************************************/
void display(void) {

	cout<<"===> DISPLAY"<<endl;

	if (combat == NULL) {

		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
		glShadeModel(GL_SMOOTH);
		glEnable(GL_DEPTH_TEST);
		glClearColor(0.3, 0.3, 0.3, 0.0);

		if (loadIdentity == true) {

			cout<<"load identity = true..."<<endl;

			glLoadIdentity();
			loadIdentity = false;
		}

		// Dessine la scene (carte, territoire)
		drawScene(GL_RENDER);

		// Si le menu des scores est actif
		if (menuScore == true) {

			// On l'affiche
			afficheMenuScores();
			reshape(800, 600);
			glutSwapBuffers();
		}

		// Si le menu d'aide est actif
		if (menuAide == true) {

			// On l'affiche
			afficheMenuAide();
			reshape(800, 600);
			glutSwapBuffers();
		}

		// Si le menu d'aide est actif
		if (menuResultat == true) {

			// On l'affiche
			afficheMenuResultat();
			reshape(800, 600);
			glutSwapBuffers();
		}

	} else { // combat != NULL on a affiche l'animation de combat

		menuScore = false; // desactivation du menu des scores
		loadIdentity = true;

		// On affiche le boulier
		boulier->display();
		glutSwapBuffers();

	}
}

/**********************************************************
 * Gestion des evenements claviers
 * - x : avancer la camera sur l'axe des x
 * - X : reculer la camera sur l'axe des x
 * - y : avancer la camera sur l'axe des y
 * - Y : reculer la camera sur l'axe des y
 * - z : avancer la camera sur l'axe des z
 * - Z : reculer la camera sur l'axe des z
 * - 0 : Remise a 0 du territoire en cours et action
 * - 2 : Vue 2D
 * - 3 : vue 3D
 * - + : ajouter une armee sur le territoire
 * - - : enlever une armee sur le territoire
 * - a : attaquer
 * - h : afficher le menu d'aide
 * - q : sortir du boulier
 * - r : masquer le menu de resultats
 **********************************************************/
void clavier(unsigned char key, int x, int y) {

	switch (key) {
	case 'x':
		eX=eX+pasCamera;
		break;
	case 'X':
		eX=eX-pasCamera;
		break;
	case 'y':
		eY=eY+pasCamera;
		break;
	case 'Y':
		eY=eY-pasCamera;
		break;
	case 'z':
		eZ=eZ+pasCamera;
		break;
	case 'Z':
		eZ=eZ-pasCamera;
		break;

	case 'o':
		// position origine				
		eX = 0;
		eY = 0;
		eZ = 500;
		break;

	case '0':
		// reset action et territoire en cours		
		if (territoireEnCours != NULL)
			territoireEnCours->setCouleurCourante(territoireEnCours->couleurOrigine);
		territoireEnCours = NULL;
		combat = NULL;
		action = PLACER;
		break;

	case '2':
		// affichage de la carte en 2D
		glutTimerFunc(50, timerVue2d, 10);
		break;

	case '3':
		// affichage de la carte en 3D		
		glutTimerFunc(50, timerVue3d, 10);
		break;

	case '+':
		// Si un territoire est selectionne
		if (territoireEnCours != NULL && menuContextTerritoire) {

			// on essaye d'ajouter
			if (!territoireEnCours->ajouterArmee()) {
				messageErreur = NO_ARMEE_REST;
				SDL_CreateThread(erreur, 0);
				SDL_Delay(500);
			} else {
				SDL_CreateThread(delArmee, 0);
				SDL_Delay(500);
			}
		}
		break;

	case '-':
		// Si un territoire est selectionne
		if (territoireEnCours != NULL && menuContextTerritoire) {

			// on essaye de retirer une armee
			if (!territoireEnCours->retirerArmee()) {
				messageErreur = UNE_ARMEE_MIN;
				SDL_CreateThread(erreur, 0);
				SDL_Delay(500);
			} else {
				SDL_CreateThread(delArmee, 0);
				SDL_Delay(500);
			}
		}
		break;

	case 'a': // Attaque
		if (territoireEnCours != NULL && menuContextTerritoire) {
			action = ATTAQUER;
		}
		break;

	case 'h':

		// Si le menu d'aide est active on le descative
		if (menuAide == true)
			menuAide = false;

		// Sinon on l'active
		else
			menuAide = true;

		SDL_CreateThread(aide, 0);
		SDL_Delay(500);
		break;

	case 'r':

		// Si le menu de resultat est active
		if (menuResultat == true) {

			cout << "masquage du menu de resultat" <<endl;
			// On le cache
			menuResultat = false;
			combatAffichage = NULL;

			SDL_CreateThread(aide, 0);
			SDL_Delay(500);
		}
		break;

	case 13: // Quitter le boulier
	{
		if (combat == NULL)
			break;

		glClearColor(0.3, 0.3, 0.3, 0.0);
		cout << "on quitte le boulier" << endl;

		// Arret des sons du boulier
		lCri->stop();
		lFoudre->stop();
		lGhost->stop();
		lTempete->stop();

		// Lancement du combat
		combat->combattre(boulier->resultatAttaque, boulier->resultatDefense);

		// Affichage du combat
		combat->afficher();

		// Explosion
		SDL_CreateThread(explose, 0);
		SDL_Delay(500);

		// Suppresion du combat
		combatAffichage = combat;
		combat = NULL;

		// Action par defaut a placer
		action = PLACER;

		// Relance la musique de fond
		lAmbianceCourante->lecture();

		// Reactive le menu des scores et des resultat du combat		
		menuScore = true;
		menuResultat = true;

		// Changement du joueur en cours
		joueurEnCours = risk->getJoueurSuivant(joueurEnCours);

		break;
	}

	case 27:
		SDL_CreateThread(fin, 0);
		SDL_Delay(2500);
		SDL_Quit();
		exit(0);
		boulier->~Boulier();
		break;
	}

	glutPostRedisplay();
}
/**********************************************************
 * Gestion special des evenements claviers (fleches)
 * - KEY_UP   : augmenter le volume de la musique de fond
 * - KEY_DOWN : reduire le volume de la musique de fond
 * - KEY_RIGHT: changer la musique de fond
 **********************************************************/
void clavierSpecial(int key, int x, int y) {

	switch (key) {

	case GLUT_KEY_UP:
		cout << "volume +"<<endl;
		lAmbianceCourante->volume = lAmbianceCourante->volume + pasVolume;
		break;

	case GLUT_KEY_DOWN:
		cout << "volume -"<<endl;
		lAmbianceCourante->volume = lAmbianceCourante->volume - pasVolume;
		break;

	case GLUT_KEY_RIGHT:
		lAmbianceCourante->stop();
		changeMusiqueAmbiance(numAmbianceCourante);
		messageErreur = MUSIQUE_CGH;
		lAmbianceCourante->lecture();
		break;
	}
	glutPostRedisplay();
}

void gererMenuTerritoire(int value) {
	clavier(value, 0, 0);
}

/**********************************************************
 * fonction retourne le territoire selectionne sur la carte
 **********************************************************/
Territoire* getTerritoireFromCarte(GLint hits, GLuint buffer[]) {

	int i, j, names;
	GLuint *ptr;

	ptr = (GLuint *) buffer;
	for (i = 0; i < hits; i++) {
		names = (int) *ptr;

		ptr++;
		ptr++;
		ptr++;

		for (j = 0; j < names; j++, ptr++) {
			cout << "Territoire selectionne "<< i<<" id = "<< *ptr<<endl;

			// Si on a clique sur territoire (1000 = id de la carte) 			
			if ((int) *ptr != 1000) {

				cout << "traitement du territoire "<< (int) *ptr<<endl;

				Territoire* territoire = risk->getTerritoireById((int) *ptr);
				return territoire;
			}
		}
	}
	return NULL;
}

/**********************************************************
 * Gestion des evenements souris
 * - clic gauche   = selection de territoire
 * - clic droit    = menu pour ajouter/enlever le nombre d'armee
 * - roulette bas  = zoomer
 * - roulette haut = dezoomer
 **********************************************************/
void souris(int button, int state, int x, int y) {

	// clic gauche de souris
	if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {

		if (combat != NULL)
			return;

		cout << "=> SOURIS Gauche" << endl;

		GLuint selectBuf[BUFSIZE];
		GLint hits;
		GLint viewport[4];

		glGetIntegerv(GL_VIEWPORT, viewport);

		glSelectBuffer(BUFSIZE, selectBuf);
		(void) glRenderMode(GL_SELECT);

		glInitNames();
		glPushName(0);

		glMatrixMode(GL_PROJECTION);
		glPushMatrix();
		glLoadIdentity();

		gluPickMatrix((GLdouble) x, (GLdouble) (viewport[3] - y), 5.0, 5.0,
				viewport);
		gluPerspective(60, longueur/hauteur, 1, 800);

		// dessine la scene en mode selection (donne des identifiants aux objets)
		drawScene(GL_SELECT);

		glMatrixMode(GL_PROJECTION);
		glPopMatrix();
		glFlush();
		glPopName();

		hits = glRenderMode(GL_RENDER);

		// Recuperation du territoire selectionne				
		Territoire* territoire = getTerritoireFromCarte(hits, selectBuf);

		switch (action) {

		/******************************************************/
		case PLACER:

			// test si le territoire n'appartient pas au joueur en cours
			if (territoire != NULL && territoire->getPropretaire()
					!= joueurEnCours) {

				cout << "le territoire n'appartient pas au joueur en cours"
						<< endl;

				// Erreur
				messageErreur = SELECTION_AUTRE_USER;

				SDL_CreateThread(erreur, 0);
				SDL_Delay(500);
				territoireEnCours == NULL;
				territoire == NULL;
				break;
			}

			// Si un territoire a deja ete selectionne le coup precedent
			if (territoireEnCours != NULL && menuContextTerritoire) {

				// Si le territoire precedent a ete ameliorer (nb armee)
				if (territoireEnCours->isAmeliore()) {

					// on joue le son ameliation
					SDL_CreateThread(jobDone, 0);
					SDL_Delay(500);

					// reset le flag d'amelioration du territoire
					territoireEnCours->resetAmelioration();
				}

				// on detruit le menu contextuel attache au territoire precedent
				cout <<" destruction du menu pour le territoire "
						<<territoireEnCours->getId() <<endl;
				territoireEnCours->setCouleurCourante(territoireEnCours->couleurOrigine);
				glutDestroyMenu(menuContextTerritoire);
			}

			// changement du territoire en cours (il devient le territoire selectionne)
			territoireEnCours = territoire;

			if (territoireEnCours != NULL) {

				// On colorie le territoire en selection				
				territoireEnCours->setCouleurCourante(territoire->couleurSelection);

				// On joue le son d'interrogation/ordre
				SDL_CreateThread(what, 0);

				// Creation du menu pour le territoire	
				cout <<" creation du menu pour le territoire "
						<<territoireEnCours->getId() <<endl;

				// creation du menu pour ajouter/supprimer des armees			
				menuContextTerritoire = glutCreateMenu(gererMenuTerritoire);
				glutAddMenuEntry("Ajouter armee        (+)", '+');
				glutAddMenuEntry("Enlever armee        (-)", '-');
				glutAddMenuEntry("Attaquer un pays   (a)", 'a');

				// Attachement du menu au clic droit de la souris
				glutAttachMenu(GLUT_RIGHT_BUTTON);
				break;

			}

			/******************************************************/
		case ATTAQUER:

			// si le territoire cible n'est pas null
			if (territoire != NULL) {

				// Destruction du menu du territoire source
				glutDestroyMenu(menuContextTerritoire);

				cout << "territoire cible = " << territoire->getId()<<endl;

				// On teste la presence de frontiere
				Territoire* territoireSource = territoireEnCours;
				Territoire* territoireCible = territoire;

				cout << "recherche de frontiere..." << endl;

				// Si pas de frontiere en source et cible
				if (!risk->existFrontiere(territoireSource, territoireCible)) {
					cout << "pas de frontiere en source et cible" << endl;

					// Erreur
					messageErreur = COMBAT_NO_FRONTIERE;

					SDL_CreateThread(erreur, 0);
					SDL_Delay(500);
					break;
				}

				cout << "frontiere trouve !" << endl;

				// test si le pays appartient au joueur adverse
				Joueur* attaquant = territoireSource->getPropretaire();
				Joueur* defenseur = territoireCible->getPropretaire();

				// l'attaquant et le defenseur son la meme personne
				if (attaquant->getNom() == defenseur->getNom()) {
					cout << "la source et la cible appartienne au meme joueur"
							<< endl;

					// Erreur
					messageErreur = COMBAT_OWN_CIBLE;

					SDL_CreateThread(erreur, 0);
					SDL_Delay(500);
					break;
				}

				// Tous les test sont passe avec succes on peut creer un combat
				// Joue le son d'attaque			
				SDL_CreateThread(attack, 0);
				SDL_Delay(500);

				territoireCible->setCouleurCourante(territoireCible->couleurSelection);

				cout << "creation d'un combat" << endl;

				// Creation d'un combat
				combat = riskFactory->creerCombat();

				// Affectation des territoire engages
				combat->setPaysAttaque(territoireSource);
				combat->setPaysDefense(territoireCible);

				// Affectation des joueurs engages
				combat->setAttaquant(territoireSource->getPropretaire());
				combat->setDefenseur(territoireCible->getPropretaire());

				// descativation du menu des scores
				menuScore = false;

				// On lance le timer qui va realiser le display du boulier
				lancerAction = true;

				//*****modif youenn
				//lancement du boulier

				lAmbianceCourante->stop();

				//affectation du nombre d'arme en attaque et defense selon les armes dispo
				int nbEnAttaque;
				int nbEnDefense;

				if (territoireSource->getNbArmee()>3)
					nbEnAttaque = 3;
				else
					nbEnAttaque = territoireSource->getNbArmee();

				if (territoireCible->getNbArmee()>3)
					nbEnDefense = 3;
				else
					nbEnDefense = territoireCible->getNbArmee();

				boulier->maj(nbEnAttaque, nbEnDefense); //mise a jour du boulier pour les coups suivants

				//**********

				break;
			}
		}
	}

	// Roulette bas zoomer
	if (button == 3) {
		if (eZ < 500)
			eZ = eZ + pasCamera;
		else {
			if (eY < 0)
				eY = eY + pasCamera;
		}

	}

	// Roulette haut dezoomer
	else if (button == 4) {
		if (eY > -250)
			eY = eY - pasCamera;
		else {
			if (eZ > 250)
				eZ = eZ - pasCamera;
		}
	}
	glutPostRedisplay();
}

/**********************************************************
 * Fonction qui affiche ma carte en 3d
 **********************************************************/
void timerVue3d(int id) {

	cout << "timer vue 3d"<<endl;
	cout << "eZ = " <<eZ<< " eY = "<<eY<<endl;

	// Si les coordonee correspondent deja a la vue 3d
	if (eY == -250 && eZ == 490) {
		vue3d = true;
		return;
	} else {
		vue3d = false;
	}

	if (vue3d == false) {

		if (eY > -250)
			eY = eY - pasCamera;
		else {
			if (eZ > 490)
				eZ = eZ - pasCamera;
		}

		if (eZ < 490)
			eZ = eZ + pasCamera;
		else {
			if (eY < -250)
				eY = eY + pasCamera;
		}

		glutTimerFunc(50, timerVue3d, 10);
		glutPostRedisplay();
	}
}

/**********************************************************
 * Fonction qui affiche la carte en 2d
 **********************************************************/
void timerVue2d(int id) {

	cout << "timer vue 2d"<<endl;
	cout << "eZ = " <<eZ<< " eY = "<<eY<<endl;

	// Si les coordonee correspondent deja a la vue 2d
	if (eZ == 500 && eY == 0) {
		vue2d = true;
		return;
	} else {
		vue2d = false;
	}

	if (vue2d == false) {

		if (eZ < 500)
			eZ = eZ + pasCamera;
		else {
			if (eY < 0)
				eY = eY + pasCamera;
		}
	}

	glutTimerFunc(50, timerVue2d, 10);
	glutPostRedisplay();

}

/**********************************************************
 * fonction timer qui lance l'animation du boulier
 **********************************************************/
void timer(int x) {

	if (combat != NULL) {
		boulier->timer(x);
		glutPostRedisplay();
	}

	/*if (lancerAction) { // Lancement du boulier

	 lAmbiance->stop();
	 //boulier = new Boulier();

	 if (initBoulier==false) {

	 //premiere initialisation
	 boulier->init(lGrincement, lCri, lFoudre, lGhost, lTempete, sRebond);
	 initBoulier = true;
	 } else
	 boulier->maj(3,3); //mise a jour du boulier pour les coups suivants

	 //startBoulier = true;
	 lancerAction = false;
	 }
	 */
	glutTimerFunc(50, timer, 10);
	/*if (combat == NULL)
	 glutPostRedisplay();
	 */
}

/**********************************************************
 * Initialisation avant display
 **********************************************************/
void init(void) {

	glGenTextures(1, texName);

	action = PLACER;
	initTexCarte();
	lAmbianceCourante = lAmbiance1;
	lAmbianceCourante->lecture();
}

/**********************************************************
 * Initialisation du Jeu
 * - creation du jeu
 * - creation des joueurs
 * - creation du monde (continent, territoire, frontiere)
 **********************************************************/
void initMonde() {

	cout <<"init monde..."<<endl;

	risk = Jeu::getInstance();
	risk->initJeu(Jeu::NBJOUEUR);

	lesJoueurs = risk->getJoueurs();
	lesTerritoires = risk->getMonde()->getTerritoires();

	joueurEnCours = lesJoueurs[1];

	cout << endl;
	cout << "************" << endl;
	cout << "Pret a jouer" << endl;
	cout << "************" << endl;
	cout << endl;

}

/**********************************************************
 * fonction MAIN
 **********************************************************/
int main(int argc, char** argv) {

	// Initialisation de la RiskFactory
	riskFactory = RiskFactory::getInstance();

	// Initialisation de SDL
	if (SDL_Init(SDL_INIT_AUDIO) < 0) {
		fprintf(stderr, "Erreur d'initialisation de SDL : %s.\n", SDL_GetError());
		exit(EXIT_FAILURE);
	}

	// Initialisation du jeu
	initMonde();

	// Creation de la fenetre opengl
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
	glutInitWindowSize(800, 600);
	glutInitWindowPosition(100, 100);
	winIdMain= glutCreateWindow("Risk Orc Vs Humain");

	// Initialisation	
	init();

	glutReshapeFunc(reshape); // fonction de reshape
	glutDisplayFunc(display); // fonction qui gere l'affichage
	glutTimerFunc(50, timer, 10); // fonction timer
	//glutTimerFunc(50, timerVue3d, 10); // fonction timerVue3d(1);
	glutMouseFunc(souris); // gestion des evenements souris
	glutKeyboardFunc(clavier); // gestion des evenements claviers	
	glutSpecialFunc(clavierSpecial);

	srand(time(NULL)); // initialisation de la fonction aleatoire en fonction du temps

	boulier = new Boulier();

	boulier->init(lGrincement, lCri, lFoudre, lGhost, lTempete, sRebond);
	initBoulier = true;
	glutPostRedisplay();
	glFlush();
	glutSwapBuffers();
	lecteur.lecture(); // demarrage du lecteur audio 

	SDL_CreateThread(demarre, 0); // lance le son de demarrage
	glutMainLoop();

	return 0;
}

/********************************************************************
 * Fonction appelee par des thread SDL
 * - what
 * - attack
 * - jobDone
 * - explose
 * - demarre
 * - erreur
 * - addArmee
 * - delArmee
 * - fin
 ********************************************************************/

/*******************************************************
 * fonction qui appel le son de musique d'ambiance 
 ******************************************************/
void changeMusiqueAmbiance(int numAmbiance) {

	switch (numAmbianceCourante) {

	case NUM_AMBIANCE_1:
		lAmbianceCourante = lAmbiance2;
		numAmbianceCourante = NUM_AMBIANCE_2;
		break;

	case NUM_AMBIANCE_2:
		lAmbianceCourante = lAmbiance1;
		numAmbianceCourante = NUM_AMBIANCE_1;
		break;
	}
}

/*******************************************************
 * fonction qui appel le son de selection du terrioire 
 *******************************************************/
int what(void * param) {

	int race = joueurEnCours->getRace();
	int whatEnCours = joueurEnCours->getWhatEnCours();

	switch (race) {

	case Joueur::HUMAIN:

		switch (whatEnCours) {

		case 1:
			LectureRVVB::creer_volatile(&sHumainWhat1, 1, 1, 0.5);
			joueurEnCours->setWhatEnCours(2);
			break;

		case 2:
			LectureRVVB::creer_volatile(&sHumainWhat2, 1, 1, 0.5);
			joueurEnCours->setWhatEnCours(3);
			break;

		case 3:
			LectureRVVB::creer_volatile(&sHumainWhat3, 1, 1, 0.5);
			joueurEnCours->setWhatEnCours(1);
			break;
		}

		break;

	case Joueur::ORC:

		switch (whatEnCours) {

		case 1:
			LectureRVVB::creer_volatile(&sOrcWhat1, 1, 1, 0.5);
			joueurEnCours->setWhatEnCours(2);
			break;

		case 2:
			LectureRVVB::creer_volatile(&sOrcWhat2, 1, 1, 0.5);
			joueurEnCours->setWhatEnCours(3);
			break;

		case 3:
			LectureRVVB::creer_volatile(&sOrcWhat3, 1, 1, 0.5);
			joueurEnCours->setWhatEnCours(1);
			break;
		}
		break;
	}

	return 0;
}

/*******************************************************
 * fonction qui appel le son d'attaque 
 ******************************************************/
int attack(void * param) {

	cout << "------------- jouer son attaque "<< endl;

	int race = joueurEnCours->getRace();
	int attackEnCours = joueurEnCours->getAttackEnCours();

	switch (race) {

	case Joueur::HUMAIN:

		switch (attackEnCours) {

		case 1:
			LectureRVVB::creer_volatile(&sHumainAttack1, 1, 1, 0.5);
			joueurEnCours->setAttackEnCours(2);
			break;

		case 2:
			LectureRVVB::creer_volatile(&sHumainAttack2, 1, 1, 0.5);
			joueurEnCours->setAttackEnCours(3);
			break;

		case 3:
			LectureRVVB::creer_volatile(&sHumainAttack3, 1, 1, 0.5);
			joueurEnCours->setAttackEnCours(1);
			break;
		}

		break;

	case Joueur::ORC:

		cout << "------------- jouer son orc "<<attackEnCours<< endl;

		switch (attackEnCours) {

		case 1:

			LectureRVVB::creer_volatile(&sOrcAttack1, 1, 1, 0.5);
			joueurEnCours->setAttackEnCours(2);
			break;

		case 2:
			LectureRVVB::creer_volatile(&sOrcAttack2, 1, 1, 0.5);
			joueurEnCours->setAttackEnCours(3);
			break;

		case 3:
			LectureRVVB::creer_volatile(&sOrcAttack3, 1, 1, 0.5);
			joueurEnCours->setAttackEnCours(1);
			break;
		}

		break;
	}

	return 0;
}

/*******************************************************
 * fonction qui appel le son travail termine/amelioration 
 ******************************************************/
int jobDone(void * param) {

	int race = joueurEnCours->getRace();

	switch (race) {
	case Joueur::HUMAIN:
		LectureRVVB::creer_volatile(&sHumainJobDone, 1, 1, 0.5);
		break;
	case Joueur::ORC:
		LectureRVVB::creer_volatile(&sOrcJobDone, 1, 1, 0.5);
		break;
	}
	return 0;
}
/*******************************************************
 * fonction qui appel le son d'explosion 
 *******************************************************/
int explose(void * param) {
	LectureRVVB::creer_volatile(&sExplosion, 1, 1, 0.5);
	return 0;
}
/*******************************************************
 * fonction qui appel le son de demarrage du jeu
 *******************************************************/
int demarre(void * param) {
	LectureRVVB::creer_volatile(&sDepart, 1, 1, 0.5);
	return 0;
}
/*******************************************************
 * fonction qui appel le son d'erreur
 *******************************************************/
int erreur(void * param) {
	LectureRVVB::creer_volatile(&sError, 3, 1, 0.5);
	return 0;
}
/*******************************************************
 * fonction qui appel le son de d'ajout d'armee
 *******************************************************/
int addArmee(void * param) {
	LectureRVVB::creer_volatile(&sAddArmee, 1, 1, 0.5);
	return 0;
}
/*******************************************************
 * fonction qui appel le son de suppression d'armee
 *******************************************************/
int delArmee(void * param) {
	LectureRVVB::creer_volatile(&sAddArmee, 1, 1, 0.5);
	return 0;
}
/*******************************************************
 * fonction qui appel le son d'affichage de l'aide
 *******************************************************/
int aide(void * param) {
	LectureRVVB::creer_volatile(&sAfficheAide, 1, 1, 0.5);
	return 0;
}
/*******************************************************
 * fonction qui appel le son de fin
 *******************************************************/
int fin(void * param) {
	LectureRVVB::creer_volatile(&sFin, 1, 1, 0.5);
	return 0;
}

